<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8'>
<title>cube WebGL 2.0</title>

</head>
<body>

<script id="draw-shader-vs" type="x-shader/x-vertex">#version 300 es
precision highp float;

in vec3 inPos;
in vec3 inNV;
in vec3 inCol;

out vec3  vertPos;
out vec3  vertNV;
out vec3  vertCol;

uniform mat4 u_projectionMat44;
uniform mat4 u_viewMat44;
uniform mat4 u_modelMat44;
uniform vec4 u_clipPlane;

void main()
{   
    mat4 mv       = u_viewMat44 * u_modelMat44; 
    vertCol       = inCol;
    vertNV        = normalize(mat3(mv) * inNV);
    vec4 viewPos  = mv * vec4( inPos, 1.0 );
    vertPos       = viewPos.xyz;
    gl_Position   = u_projectionMat44 * viewPos;
}
</script>

<script id="draw-shader-fs" type="x-shader/x-fragment">#version 300 es
precision mediump float;

in vec3  vertPos;
in vec3  vertNV;
in vec3  vertCol;

out vec4 fragColor;

void main()
{
    vec3 color = vertCol;
    fragColor  = vec4( color.rgb, 1.0 );
} 
</script>

<style>
html,body { margin: 0; overflow: hidden; }
#gui { position : absolute; top : 0; left : 0; font-size : large; }
#ref-link { position : absolute; bottom : 0; left : 0; font-size : large; }  
</style>

<!--div>
<form id="gui" name="inputs">
  <table>
      <tr> <td> <font color= #CCF></font> </td> 
              <td> <input type="range" id="" min="0" max="100" value="50" onchange="changeEventHandler(event);"/></td> </tr>
  </table>
</form>
</div-->

<!--div id="ref-link">
  <a href=""> 
  </a>
</div-->

<canvas id="canvas" style="border: none;"></canvas>

<script>var exports = {"__esModule": true}; require = function(name) {}; </script>
<script src="./utility/MathUtility.js"></script>
<script src="./utility/Camera.js"></script>
<script src="./webgl/ShaderProgram.js"></script>
<script src="./webgl2/VertexArrayObject.js"></script>

<script>
(function loadscene() {
    class App {
        constructor() {
            this.vp_size = [0, 0];
            this.canvas = document.getElementById("canvas");
            //this.gl = this.canvas.getContext( "webgl" );
            //this.gl = this.canvas.getContext( "experimental-webgl" );
            this.gl = this.canvas.getContext("webgl2");
            if (!this.gl)
                return null;
            //let ext_standard_derivatives = this.gl.getExtension("OES_standard_derivatives");  // dFdx, dFdy
            //if (!ext_standard_derivatives)
            //    console.log('no standard derivatives support (no dFdx, dFdy)');
            //let ext_vao = this.gl.getExtension("OES_vertex_array_object"); 
            //if (!ext_vao)
            //    console.log('no vertex array objects support');
            this.progDraw = new ShProg(this.gl, [{ source: "draw-shader-vs", stage: this.gl.VERTEX_SHADER },
                { source: "draw-shader-fs", stage: this.gl.FRAGMENT_SHADER }
            ]);
            if (!this.progDraw.progObj)
                return null;
            this.progDraw.inPos = this.progDraw.AttrI("inPos");
            this.progDraw.inNV = this.progDraw.AttrI("inNV");
            this.progDraw.inCol = this.progDraw.AttrI("inCol");
            // create cube
            let cubePos = [
                -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0,
                -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0
            ];
            let cubeCol = [1.0, 0.0, 0.0, 1.0, 0.5, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0];
            let cubeHlpInx = [0, 1, 2, 3, 1, 5, 6, 2, 5, 4, 7, 6, 4, 0, 3, 7, 3, 2, 6, 7, 1, 0, 4, 5];
            let cubePosData = [];
            for (let i = 0; i < cubeHlpInx.length; ++i) {
                cubePosData.push(cubePos[cubeHlpInx[i] * 3], cubePos[cubeHlpInx[i] * 3 + 1], cubePos[cubeHlpInx[i] * 3 + 2]);
            }
            let cubeNVData = [];
            for (let i1 = 0; i1 < cubeHlpInx.length; i1 += 4) {
                let nv = [0, 0, 0];
                for (let i2 = 0; i2 < 4; ++i2) {
                    let i = i1 + i2;
                    nv[0] += cubePosData[i * 3];
                    nv[1] += cubePosData[i * 3 + 1];
                    nv[2] += cubePosData[i * 3 + 2];
                }
                for (let i2 = 0; i2 < 4; ++i2)
                    cubeNVData.push(nv[0], nv[1], nv[2]);
            }
            let cubeColData = [];
            for (let is = 0; is < 6; ++is) {
                for (let ip = 0; ip < 4; ++ip) {
                    cubeColData.push(cubeCol[is * 3], cubeCol[is * 3 + 1], cubeCol[is * 3 + 2]);
                }
            }
            let cubeInxData = [];
            for (let i = 0; i < cubeHlpInx.length; i += 4) {
                cubeInxData.push(i, i + 1, i + 2, i, i + 2, i + 3);
            }
            this.bufCube = new VertexArrayObject(this.gl, [{ data: cubePosData, attrSize: 3, attrLoc: this.progDraw.inPos },
                { data: cubeNVData, attrSize: 3, attrLoc: this.progDraw.inNV },
                { data: cubeColData, attrSize: 3, attrLoc: this.progDraw.inCol }], cubeInxData);
            this.resize();
            this.camera = new Camera(this.gl.canvas, [0, 3, 0.0], [0, 0, 0], [0, 0, 1], 90, this.vp_size, 0.5, 100);
            let self = this;
            window.onresize = function () { self.resize(); };
        }
        resize() {
            //vp_size = [gl.drawingBufferWidth, gl.drawingBufferHeight];
            this.vp_size = [window.innerWidth, window.innerHeight];
            this.canvas.width = this.vp_size[0];
            this.canvas.height = this.vp_size[1];
        }
        draw(deltaMS) {
            // setup view projection and model
            this.camera.Update(this.vp_size);
            let modelMat = Mat44.ident();
            modelMat = this.camera.autoModelMatrix;
            this.gl.viewport(0, 0, this.vp_size[0], this.vp_size[1]);
            this.gl.enable(this.gl.DEPTH_TEST);
            this.gl.clearColor(0.0, 0.0, 0.0, 1.0);
            this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT);
            // set up draw shader
            this.progDraw.Use();
            this.progDraw.SetM44("u_projectionMat44", this.camera.perspective);
            this.progDraw.SetM44("u_viewMat44", this.camera.orbit);
            this.progDraw.SetM44("u_modelMat44", modelMat);
            // draw scene
            this.bufCube.draw();
        }
    }
    function render(deltaMS) {
        app.draw(deltaMS);
        requestAnimationFrame(render);
    }
    let app = new App();
    requestAnimationFrame(render);
})();
</script>

</body>
</html>